#include <stdio.h>
#include<string.h>
#include <stdlib.h>
#define SIZE 512
#define ZERO '\0'
#include<errno.h>
#define DELIM " "
#include<unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#define SkipPath(p) do{p=p+strlen(p)-1;while(*p!='/'){p--;}}while(0)
char *Argv[30];
char ConmandLine [SIZE];
char cwd[SIZE*2];
int lastcode;
char* Getuser()
{
  char* user=getenv("USER");
  return user;
}

char* Gethostname()
{
  char* hostname=getenv("HOSTNAME");
  return hostname;
}

char* Getpwd()
{
  char* pwd=getenv("PWD");
  return pwd;
}
void MakeConmandLineAndPrintf(char arr[],size_t size)
{

  char* Cwd=Getpwd();
  SkipPath(Cwd);
  snprintf(arr,size,"[%s@%s %s]>",Getuser(),Gethostname(),strlen(Cwd)==1?"/":Cwd+1);
  printf("%s",arr);
  fflush(stdout);
}
int GetCommand(char arr[],size_t size)
{
  char* comand=fgets(arr,size,stdin);
  if(comand==NULL) return -1;

  comand[strlen(comand)-1]=ZERO;
  return strlen(arr);
}
void splitcommand(char command[],size_t size)
{ 
  Argv[0]= strtok(command,DELIM);
  int i=1;
  while((Argv[i++]=strtok(NULL,DELIM)));
}
void Die()
{
  exit(-1);
}
void ExucuteCommand()
{

  pid_t id=fork();
  if(id<0) Die();
  else if(id==0)
  {
    execvp(Argv[0],Argv);
    exit(errno);
  }
  else{
    int status=0;
    pid_t rid=waitpid(id,&status,0);
    if(rid>0)
    {
      lastcode= WEXITSTATUS(status);
    }
  }
}
char* Gethome()
{
  char*tmp= getenv("HOME");
  return tmp;
}
void cd()
{
  char*path=Argv[1];
  printf("cd :  %s\n", path);
  if(path==NULL) path=Gethome();
  chdir(path);
  getcwd(cwd,sizeof(cwd));
  setenv("PWD", cwd, 1);
}
void echo_stast()
{
  printf("%d\n",lastcode);
}
int CheckBuildin()
{
  int yes=0;
  const char* enter_cmd=Argv[0];
  if(strcmp(enter_cmd,"cd")==0)
  {
    yes=1;
    cd();
  }
  if(strcmp(enter_cmd,"echo")==0&&strcmp(Argv[1],"$?")==0)
  {
    echo_stast();
    printf("AAAA");
    yes =1;
  }
  return yes;
}
int main()
{
  int quit=0;
  char usercommand[SIZE];
  while(!quit)
  {
    MakeConmandLineAndPrintf(ConmandLine,sizeof(ConmandLine));
    GetCommand(usercommand,sizeof(usercommand));
    splitcommand(usercommand,sizeof(usercommand));
    int n=CheckBuildin();
    if(n!=0)  continue;
    ExucuteCommand();
  }  
  return 0;
}
